/*
 * @Author: ZhanXie
 * @Date: 2019-11-25 17:15:41
 * @LastEditors: ZhanXie
 * @LastEditTime: 2020-05-06 15:40:31
 * @Description: 业务相关
 * @FilePath: \projectStudy\node-demo\blog-origin\app.js
 */
const querystring = require('querystring')
const handleBlogRouter = require('./src/router/blog')
const handleUserRouter = require('./src/router/user')
const {
  get,
  set
} = require('./src/db/redis')
const { access } = require('./src/util/log')

/**
 * 获取 cookie 的过期时间
 * 1天后过期
 */
const getCookieExpires = () => {
  const d = new Date()
  d.setTime(d.getTime() + (24 * 60 * 60 * 1000))
  return d.toGMTString()
}

// session 数据
// const SESSION_DATA = {}

/**
 * @description: 用于处理 post data
 *  如果 method !== POST || content-type !== 'application/json' 不处理,直接返回{}
 * 一点一点接收,监听 end 事件结束的时候返回数据
 *  
 * @param {type} 
 * @return: { promise }
 */
const getPostData = req => {
  const promise = new Promise((resolve, reject) => {
    if (req.method !== 'POST') {
      resolve({})
      return
    }
    if (req.headers['content-type'] !== 'application/json') {
      resolve({})
      return
    }
    let postData = ''
    req.on('data', chunk => {
      postData += chunk.toString()
    })
    req.on('end', () => {
      if (!postData) {
        resolve({})
        return
      }
      resolve(JSON.parse(postData))
    })
  })
  return promise
}

const serverHandle = (req, res) => {
  // 记录 access
  access(`${req.method} -- ${req.url} -- ${req.headers['user-agent']} -- ${Date.now()}`)

  // 设置返回格式 json
  res.setHeader('Content-Type', 'application/json')

  /**
   * 获取 path
   * 通过截取 url ? 前半部分,并且赋值给 req.path
   */
  const url = req.url
  req.path = url.split('?')[0]

  /**
   * 解析 query
   * 通过截取 url ? 后半部分,并且赋值给 req.query
   */
  req.query = querystring.parse(url.split('?')[1])

  /**
   * 获取浏览器的cookie,并且赋值给 req.cookie
   */
  req.cookie = {}
  const cookieStr = req.headers.cookie || '' // k1=v1;k2=v2;k3=v3
  cookieStr.split(';').forEach(item => {
    if (!item) {
      return
    }
    const arr = item.split('=')
    const key = arr[0].trim()
    const val = arr[1].trim()
    req.cookie[key] = val
  })

  /**
   * 解析 session
   * cookie 里面如果没有 userid 重新生成 userid
   * cookie 里面有 userid 可是没关联到 session 的时候关联，初始化
   * cookie 里面有 userid 并且已经存到 session 的时候 直接取当前 session[userid] 里的参数
   * 赋值到 req.session
   */
  // let needSetCookie = false // 是否需要设置cookie
  // let userId = req.cookie.userid
  // if (userId) {
  //   if (!SESSION_DATA[userId]) {
  //     SESSION_DATA[userId] = {}
  //   }
  // } else {
  //   needSetCookie = true
  //   userId = `${Date.now()}_${Math.random()}`
  //   SESSION_DATA[userId] = {}
  // }
  // req.session = SESSION_DATA[userId]

  /**
   * 解析 session 使用(redis)
   * cookie 里面如果没有 userid 重新根据规则生成一个不重复的 userid,并初始化 redis 中 session 的初始值
   * cookie 里面如果有 userid 赋值给 req.sessionId
   * 如果 redis 已经存在 userid 取出来赋值给 req.session,否则初始化 redis 中 session 的初始值
   */
  let needSetCookie = false // 是否需要设置 cookie
  let userId = req.cookie.userid
  if (!userId) {
    // cookie 里面如果没有 userid 重新根据规则生成一个不重复的 userid,并初始化 redis 中 session 的初始值
    needSetCookie = true
    userId = `${Date.now()}_${Math.random()}`
    // 初始化redis 中session的初始值
    set(userId, {})
  }
  // 为req创建一个sessionId属性，
  req.sessionId = userId
  get(req.sessionId)
  // 已经为用户生成了 userid
    .then(sessionData => {
      if (!sessionData) {
        // 初始化 redis 中的 session 的初始值
        set(req.sessionId, {})
        // 设置 session
        req.session = {}
      } else {
        req.session = sessionData
      }
      return getPostData(req)
    })
    .then(postData => {
      // 处理 post data,赋值给 req.body
      req.body = postData

      // 处理 blog 路由
      // const blogData = handleBlogRouter(req, res)
      // if (blogData) {
      //   res.end(JSON.stringify(blogData))
      //   return
      // }
      const blogResult = handleBlogRouter(req, res)
      if (blogResult) {
        blogResult.then(blogData => {
          if (needSetCookie) {
            // 如果用户清除了 cookie 则需要重新发放 cookie
            res.setHeader('Set-Cookie', `userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}`)
          }
          res.end(JSON.stringify(blogData))
        })
        return
      }

      // 处理 user 路由
      // const userData = handleUserRouter(req, res)
      // if (userData) {
      //   res.end(JSON.stringify(userData))
      //   return
      // }
      const userResult = handleUserRouter(req, res)
      if (userResult) {
        userResult.then(userData => {
          if (needSetCookie) {
            res.setHeader('Set-Cookie', `userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}`)
          }
          res.end(JSON.stringify(userData))
        })
        return
      }

      // 未命中路由 返回404
      res.writeHead(404, { 'Content-Type': 'text/plain' })
      res.write("404 Not Found\n")
      res.end()
    })
}

module.exports = serverHandle

// process.env.NODE_ENV

// https://dev.mysql.com/downloads/mysql


// int bigint varchar(20) longtext